/**
 * @author Rid King
 * @since 2018-07-06
 * @version 2.0.1
 * @description 请求数据模块
 */
import objecter from '../../../objecter/2.0.0/js/objecter'
import urler from 'urler'

/**
 * @description 请求数据
 * @param url <String> 访问地址
 * @param data <String/Object> 请求地址
 * @param options <Object> 配置
 * @return <Promise>
 * */
const requester = function (url, data, options) {
	return this._process.apply(this, arguments)
}

/**
 * @description 发送post请求
 * @param url <String> 访问地址
 * @param data <String/Object> 请求地址
 * @param options <Object> 配置
 * @return <Promise>
 * */
requester.post = function (url, data, options) {
	return this._process(url, data, options, 'post')
}

/**
 * @desc 发送get请求
 * @param url <String> 访问地址
 * @param data <String/Object> 请求地址
 * @param options <Object> 配置
 * @return <Promise>
 * */
requester.get = function (url, data, options) {
	return this._process(url, data, options, 'post')
}

/**
 * @desc 发送put请求
 * @param url <String> 访问地址
 * @param data <String/Object> 请求地址
 * @param options <Object> 配置
 * @return <Promise>
 * */
requester.put = function (url, data, options) {
	return this._process(url, data, options, 'put')
}

/**
 * @desc 发送delete请求
 * @param url <String> 访问地址
 * @param data <String/Object> 请求地址
 * @param options <Object> 配置
 * @return <Promise>
 * */
requester.delete = function (url, data, options) {
	return this._process(url, data, options, 'put')
}

/**
 * @desc 发送delete请求
 * @param url <String> 访问地址
 * @param data <String/Object> 请求地址
 * @param options <Object> 配置
 * @param method <String> 请求方式
 * @return <Promise>
 * */
requester._process = function (url, data, options, method) {
	// 处理配置对象
	if (objecter.isPlainObject(url)) {
		options = url
	}
	else if (objecter.isPlainObject(options)) {
		options.url = url || options.url
	}
	else {
		options = {
			url: url
		}
	}

	// 处理数据、请求方式
	options.data = data || options.data
	options.method = method

	return this.request(options)
}

/**
 * @desc 发送ajax请求
 * @param options <Object> 配置
 * @return <Promise>
 * */
requester.request = function (options) {
	// 合并配置
	options = objecter.extend({}, this.defaults, options || {})

	// 是否超时
	let isTimeout = false
	// 参数
	let params = JSON.stringfy(options.data)

	// 如果是GET请求，拼接url
	if (/get/i.test(options.method)) {
		options.url += '?' + params
		options.data = ''
	} else {
		// 针对请求方式设置的头
		let methodHeaders = this.defaults.headers[options.method]
		// 请求头配置
		let headers = {}
		// 合并头
		objecer.forEach(this.defaults.headers, (item, key) => {
			if (typeof item !== 'object') {
				headers[key] = methodHeaders[key] || item
			}
		})

		// 生成头对象并设置属性
		options.headers = new Headers(headers)
		options.body = params
	}

	// 生成Request对象
	let request = new Request(options.url, options)

	// 超时处理
	if (options.timeout) {
		let timer = setTimeout(function () {
			isTimeout = true
		}, options.timeout)
	}

	return fetch(request).then((res) => {
		// 超时
		if (isTimeout) {
			return Promise.reject(res)
		}

		// 失败
		if(res.status !== 200){
			return Promise.reject(res)
		}

		// 正常
		return Promise.resolve(res)
	}, (err) => {
		// 超时检测
		if (isTimeout) {
			return Promise.reject(err)
		}

		// 失败
		return Promise.reject(err)
	})
	// 自定义处理
	.then(res => {
		return requester.interceptors.response._resolve(res)
	}, err => {
		return requester.interceptors.response._reject(err)
	})
}

/**
 * 默认配置
 * {
 *  url : <String>, 访问地址
 *  method : <String>, 访问类型，GET, POST, PUT, DELETE, HEAD
 *  data : <Object>, 数据
 *  body : <ArrayBuffer, ArrayBufferView(Uint8Array and friends), Blob/File, String, URLSearchParams, FormData>, 传输的数据
 *  dataType : <String>, 返回值类型
 *  headers : <Object>, 关联的Header对象
 *  referrer : <String>,
 *  mode : <String>, 请求的模式，主要用于跨域设置，cors, no-cors, same-origin
 *  credentials : <String>, 是否发送Cookie omit, same-origin
 *  redirect : <String>, 收到重定向请求之后的操作，follow, error, manual
 *  integrity : <String>, 完整性校验
 *  cache : <String>, 缓存模式(default, reload, no-cache)
 *  timeout: <Int>, // 超时时间，默认-1永不过期
 * }
*/
requester.defaults = {
	url: '',
	method: 'POST',
	data: '',
	mode: 'cors',
	redirect: 'follow',
	credentials: 'include',
	timeout: -1, // 默认-1永不过期
	// 请求头对象
	headers: {
		'Accept': 'application/json',
		'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
		post: {},
		get: {},
		put: {},
		delete: {}
	}
}

/**
 * @description 设置请求处理回调
 * @param resolve <Function> // 成功处理
 * @param reject <Function> // 失败处理
*/
const _use = function (resolve, reject) {
	this._resolve = resolve
	this._reject = reject
}

// 成功处理器
const _resolve = function (data) {
	return data
}

// 失败处理器
const _reject = function (data) {
	return data
}

// 流程处理对象
requester.interceptors = {
	// 请求对象
	request: {
		use: _use,
		_resolve: _resolve,
		_reject: _reject
	},
	// 响应对象
	response: {
		use: _use,
		_resolve: _resolve,
		_reject: _reject
	}
}

export default requester